package biolabs.model.division

import biolabs.space.ContinuousPosition
import biolabs.space.DiscretePosition
import biolabs.space.GridShapedObject

import scala.collection.JavaConversions._

/**
 * A trait of a bio-object that, given a division plane,
 * determines the two starting points for the flood-fill
 * algorithm (see {@link FloodFillSpaceDivider}) that
 * divides the currently occupied space between two
 * daughter cells. The most distant point is chosen
 * from each side of the division plane.
 *
 * @author Tomas Mikula
 */
trait PlanarDivisionEndsDeterminator[
	P <: DiscretePosition[P, C],
	C <: ContinuousPosition[C, P]
]
extends DivisionEndsDeterminator[P]
{
	
self: DivisionPlaneDeterminator[C] with GridShapedObject[P, C] =>

	override def determineDivisionEnds(): (P, P) = {
		val divNormal = getDivisionPlaneNormal()
		val shape = getShape()
		assert(divNormal != null && !divNormal.isEqualTo(divNormal.zero()), "divNormal uninitialized")
		assert(shape.getVolume() > 1, "Trying to divide a 1-element cell")

		val normal = divNormal.normalized()
		val c = shape.getCenterOfGravity()
		var posd=0.0
		var negd=0.0
		var posp: P = null.asInstanceOf[P]
		var negp: P = null.asInstanceOf[P]
		for(p <- shape.getElements()){
			val vp = p.continuous().minus(c);
			val d = normal.innerProduct(vp).doubleValue()
			if(d > posd){
				posd=d; posp=p;
			} else if(d < negd){
				negd=d; negp=p;
			}
		}
		assert(posd>0 && negd<0 && posp!=null && negp!=null)
		return (negp, posp)
	}
}